package com.example.hello;

import com.example.hello.client.Navbar.BootstrapNavbarState;
import com.vaadin.shared.Connector;
import com.vaadin.ui.AbstractComponentContainer;
import com.vaadin.ui.Component;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class BootstrapNavbar extends AbstractComponentContainer {

    public enum Position {
        BOTTOM, DEFAULT, TOP, STATIC_TOP
    }

    public BootstrapNavbar() {
        setInverse(false);
        setPosition(Position.DEFAULT);
    }

    public BootstrapNavbar(Component... navs) {
        this(Position.DEFAULT, navs);
    }

    public BootstrapNavbar(Position position) {
        this(position, new LinkedList<Component>());
    }

    public BootstrapNavbar(Position position, Component... navs) {
        for (Component c : navs) {
            addNav(c);
        }
        setInverse(false);
        setPosition(position);
    }

    public BootstrapNavbar(Position position, List<Component> navs) {
        setNavs(navs);
        setInverse(false);
        setPosition(position);
    }

    public void BootstrapNavBar(List<Component> navs) {
        setNavs(navs);
    }

    public List<Component> getNavs() {
        List<Component> navs = new LinkedList<Component>();
        for (Connector connector : getState().getNavs()) {
            navs.add((Component) connector);
        }

        return navs;
    }

    public void setNavs(List<Component> navs) {
        List<Connector> connectorList = new LinkedList<Connector>();
        for (Component nav : navs) {
            connectorList.add(nav);
        }

        getState().setNavs(connectorList);
    }

    @Override
    protected BootstrapNavbarState getState() {
        return (BootstrapNavbarState) super.getState();
    }

    public void setPosition(Position position) {
        getState().setPosition(position.toString());

        markAsDirty();
    }

    public boolean isInverse() {
        return getState().isInverse();
    }

    public void setInverse(Boolean inverse) {
        getState().setInverse(inverse);

        markAsDirty();
    }

    public void addNav(Component nav) {
        addNav(nav, getState().getNavs().size());
    }

    public void addNav(Component nav, int index) {
        if (nav.getParent() != null) {
            throw new IllegalArgumentException("Given nav already has a parent component");
        }

        getState().addNav(nav, index);
        super.addComponent(nav);

        markAsDirty();
    }

    public void replaceNav(Component oldNav, Component newNav) {
        if (!getNavs().contains(oldNav)) {
            throw new IllegalArgumentException("Given old nav does not exist in this group");
        }

        int oldIndex = getState().getNavs().indexOf(oldNav);

        if (oldIndex == -1) {
            return;
        }

        removeNav(oldNav);
        addNav(newNav, oldIndex);
    }

    public void removeNav(Component nav) {
        if (!getState().getNavs().contains(nav)) {
            return;
        }

        getState().removeNav(nav);
        super.removeComponent(nav);

        markAsDirty();
    }

    public void removeAllNavs() {
        getState().getNavs().clear();
        super.removeAllComponents();

        markAsDirty();
    }

    @Override
    public void addComponent(Component c) {
        throw new UnsupportedOperationException("Use addNav method instead");
    }

    @Override
    public void removeComponent(Component c) {
        throw new UnsupportedOperationException("Use removeNav method instead");
    }

    @Override
    public void removeAllComponents() {
        throw new UnsupportedOperationException("Use removeAllNavs instead");
    }

    @Override
    public Iterator<Component> iterator() {
        return getNavs().iterator();
    }

    @Override
    public void replaceComponent(Component oldComponent, Component newComponent) {
        throw new UnsupportedOperationException("Use replaceNav method instead");
    }

    @Override
    public int getComponentCount() {
        return getState().getNavs().size();
    }

}